# -*- coding: utf-8 -*-
# @Author: Tim Liu
# @Date: 2025-01-08
# @Last Modified by: Cursor
# @Last Modified time: 2025-01-08

# @Description: api endpoints for Ontology crud

from fastapi import APIRouter, Depends, Security
from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy.orm import joinedload

from utils.response import SuccessResponse

from crewplus.helper.verify import get_api_key
from crewplus.apps.apikey.models.account_api_key import AccountApiKey

from core.database import db_getter
from core.dependencies import IdList
from core.exception import CustomException

from utils import status
from . import schemas, cruds, params, models

import logging

app = APIRouter()

###########################################################
#    Ontology API
###########################################################
@app.get("/ontologies", summary="Get ontology list")
async def get_ontologies(p: params.OntologyParams = Depends(), apikey: AccountApiKey = Security(get_api_key), db: AsyncSession = Depends(db_getter)):
    if apikey is None:
        raise CustomException("apiKey invalid", code=status.HTTP_ERROR)    
    
    model = models.OntologyDB
    options = [joinedload(model.create_user), joinedload(model.schemas)]  # Include schemas in the joinedload
    schema = schemas.OntologyFullOut
    datas, count = await cruds.OntologyDal(db).get_datas(
        **p.dict(),
        v_options=options,
        v_schema=schema,
        v_return_count=True
    )
    return SuccessResponse(datas, count=count)


@app.post("/ontology", summary="create one ontology")
async def create_ontology(data: schemas.Ontology, apikey: AccountApiKey = Security(get_api_key), db: AsyncSession = Depends(db_getter)):
    if apikey is None:
        raise CustomException("apiKey invalid", code=status.HTTP_ERROR)    
    
    data.create_user_id = apikey.user_id
    
    # Use await to ensure the operation is performed in an asynchronous context
    created_ontology = await cruds.OntologyDal(db).create_data(data=data)
        
    return SuccessResponse(created_ontology)

@app.put("/ontology/{data_id}", summary="update one ontology detail")
async def change_ontology(data_id: int, data: schemas.Ontology, apikey: AccountApiKey = Security(get_api_key), db: AsyncSession = Depends(db_getter)):
    if apikey is None:
        raise CustomException("apiKey invalid", code=status.HTTP_ERROR)    
        
    return SuccessResponse(await cruds.OntologyDal(db).put_data(data_id, data))


@app.get("/ontology/{data_id}", summary="get one ontology detail by id")
async def get_ontology(data_id: int, apikey: AccountApiKey = Security(get_api_key), db: AsyncSession = Depends(db_getter)):
    if apikey is None:
        raise CustomException("apiKey invalid", code=status.HTTP_ERROR)    
          
    schema = schemas.OntologyFullOut
    return SuccessResponse(await cruds.OntologyDal(db).get_data(data_id, v_schema=schema))


@app.delete("/ontologies", summary="batch delete ontologies", description="batch hard delete ontologies from db")
async def delete_ontologies(ids: IdList = Depends(), apikey: AccountApiKey = Security(get_api_key), db: AsyncSession = Depends(db_getter)):
    #TODO: check permission, account can only delete owned ontologies after login
    if apikey is None:
        raise CustomException("apiKey invalid", code=status.HTTP_ERROR)   
       
    await cruds.OntologyDal(db).delete_datas(ids=ids.ids, v_soft=False)
    return SuccessResponse("Successfully deleted")


@app.post("/ontology/{ontology_id}/add_schema/{schema_id}", summary="Add a schema to an ontology")
async def add_schema_to_ontology(ontology_id: int, schema_id: int, apikey: AccountApiKey = Security(get_api_key), db: AsyncSession = Depends(db_getter)):
    if apikey is None:
        raise CustomException("apiKey invalid", code=status.HTTP_ERROR)    
    
    await cruds.OntologyDal(db).add_oschema_to_ontology(ontology_id, schema_id)
    return SuccessResponse("Schema added to ontology successfully")

# New endpoint to associate multiple schemas with an ontology
@app.post("/ontology/{ontology_id}/add_schemas", response_model=None, summary="Associate multiple schemas with an ontology")
async def add_schemas_to_ontology(ontology_id: int, schema_ids: IdList = Depends(), apikey: AccountApiKey = Security(get_api_key), db: AsyncSession = Depends(db_getter)):
    if apikey is None:
        raise CustomException("apiKey invalid", code=status.HTTP_ERROR)    
    
    await cruds.OntologyDal(db).add_multiple_schemas_to_ontology(ontology_id, schema_ids.ids)
    return SuccessResponse("Schemas added to ontology successfully")